'''
Created on 29/09/2011

@author: Martin Preishuber <Martin.Preishuber@eclipt.at> "log4py author"
@author: Ike-kun <ragnell22@gmail.com>
'''

LOGLEVEL_NONE = 1 << 0
LOGLEVEL_ERROR = 1 << 1
LOGLEVEL_NORMAL = 1 << 2
LOGLEVEL_VERBOSE = 1 << 3
LOGLEVEL_DEBUG = 1 << 4

MSG_DEBUG = 1 << 0
MSG_WARN = 1 << 1
MSG_ERROR = 1 << 2
MSG_INFO = 1 << 3
MSG_FATAL = 1 << 4

LOG_MSG = {MSG_DEBUG:"DEBUG",
           MSG_WARN:"WARN",
           MSG_ERROR:"ERROR",
           MSG_INFO:"INFO",
           MSG_FATAL:"FATAL"}

LOG_LEVELS = {"DEBUG":LOGLEVEL_DEBUG,
              "VERBOSE":LOGLEVEL_VERBOSE,
              "NORMAL":LOGLEVEL_NORMAL,
              "NONE":LOGLEVEL_NONE,
              "ERROR":LOGLEVEL_ERROR}

TIME_FORMAT = {"Full":"%d/%m/%y %H:%M:%S",
               "LongTime":"%d/%m/%y",
               "ShortTime":"%H:%M:%S"}

LOG_FORMAT = {"Short":"  -  -       -  -%M",
              "Medium":"  -  -[%C.%F]-  -%D: %M",
              "Long":"%T-%L-%C [%F]-%x-%M",
              "Debug":"%T-%L-%C [%F (%N)]-%x-%M [%D (%d)]"}

from time import time, strftime, localtime
from string import join, strip
from re import sub
from Appender import CsvAppender, XmlAppender
from LogManager import LogManager
import traceback

class Logger(object):
    def __init__(self):
        self.appenders = [CsvAppender("log.csv",LOGLEVEL_NONE),
                          XmlAppender("log.xml",LOGLEVEL_NONE)]
        self.logManager = LogManager()
        self.setDefaults()
        self.initialTime = time()
        self.timeLastStep = self.initialTime
        self.openAppendFile()

    def pushNDC(self,message):
        self.logsNDC.append(message)

    def clearNDC(self):
        self.logsNDC = []

    def openAppendFile(self):
        if(self.logManager.getTarget().startswith('csv')):
            self.appenders[0].openFile()
            self.target = 'csv'
        elif(self.logManager.getTarget().startswith('xml')):
            self.appenders[1].openFile()
            self.target = 'xml'

    def closeAppendFile(self):
        if(self.target == 'csv'):
            self.appenders[0].closeFile()
        elif(self.target == 'xml'):
            self.appenders[1].closeFile()

    def debug(self, *messages):
        if(self.logLevel >= LOGLEVEL_DEBUG):
            message = self.collateMessages(messages)
            return self.showMessage(message,MSG_DEBUG)

    def warn(self, *messages):
        if(self.logLevel >= LOGLEVEL_VERBOSE):
            message = self.collateMessages(messages)
            return self.showMessage(message,MSG_WARN)

    def error(self, *messages):
        if(self.logLevel >= LOGLEVEL_ERROR):
            message = self.collateMessages(messages)
            return self.showMessage(message,MSG_ERROR)

    def info(self, *messages):
        if(self.logLevel >= LOGLEVEL_NORMAL):
            message = self.collateMessages(messages)
            return self.showMessage(message,MSG_INFO)

    def fatal(self, *messages):
        if(self.logLevel >= LOGLEVEL_ERROR):
            message = self.collateMessages(messages)
            return self.showMessage(message,MSG_FATAL)

    def collateMessages(self,messages):
        return strip(reduce(lambda x,y:"%s%s" % (x,y),messages))

    def tracestack(self):
        stack = traceback.extract_stack()
        self.lineNumber = stack[-4][1]
        self.functionName = stack[-4][2]
        if(self.functionName == "?"):
            self.functionName = "Main"

    def setDefaults(self):
        self.formatString = LOG_FORMAT[self.logManager.getFormat()]
        self.logLevel = LOG_LEVELS[self.logManager.getLogLevel()]
        self.functionName = ""
        self.lineNumber = -1
        self.timeFormat = TIME_FORMAT[self.logManager.getTimeFormat()]
        self.logsNDC = []

    def getNDC(self):
        if(len(self.logsNDC)):
            return join(self.logsNDC)
        else:
            return ""

    def getTarget(self):
        return self.target

    def showMessage(self,message,messagesource):
        currenttime = time()
        self.tracestack()
        timedifference = "%.3f" % (currenttime - self.initialTime)
        timedifflaststep = "%.3f" % (currenttime - self.timeLastStep)
        self.timeLastStep = currenttime
        timeformat = sub("%S","%S",self.timeFormat)
        currentformattedtime = strftime(timeformat,localtime(currenttime))
        line = self.formatString
        line = sub("%C", "Logger", line)
        line = sub("%D", timedifference, line)
        line = sub("%d", timedifflaststep, line)
        line = sub("%F", self.functionName, line)
        line = sub("%x", "%s" % self.getNDC(), line)
        line = sub("%L", LOG_MSG[messagesource], line)
        line = sub("%M", message, line)
        line = sub("%N", str(self.lineNumber), line)
        line = sub("%T", currentformattedtime, line)
        self.sendToAppender(line)
        return True

    def sendToAppender(self,line):
        lines = line.split("-")
        if(self.target == 'csv'):
            self.appenders[0].doAppend(lines,self.logLevel)
        elif(self.target == 'xml'):
            self.appenders[1].doAppend(lines,self.logLevel)
        else:
            print lines
